package cs304.p3.library.view;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
import java.util.Set;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import cs304.p3.library.controller.ClerkController;
import cs304.p3.library.controller.DBObjectController;
import cs304.p3.library.framework.IoC;
import cs304.p3.library.model.DBObjectForm;
import cs304.p3.library.model.DBTableModel.TableType;
import cs304.p3.library.util.SqlUtils;

@SuppressWarnings("serial")
public class DBObjectDialog extends JDialog{
	
	public static enum DBOActionType {INSERT, UPDATE, DELETE}
	
	private DBObjectController dboController = IoC.resolve(DBObjectController.class);
	private DBObjectForm dboForm = dboController.getDBObjectForm();
	private JLabel labels[];
	private JTextField textFields[];
	private JComboBox comboBox;
	private JButton actionButton, cancleButton;
	private MainFrame parent;
	
	public DBObjectDialog(MainFrame frame, String title, TableType type, DBOActionType dialogType){
		super(frame, title);
		parent = frame;
		
		//Construct labels and their respective textfields
		labels = new JLabel[type.getCount()];
		textFields = new JTextField[type.getCount()];
		int i;
		String[] labelNames = type.getLabels();
		for(i=0; i<labels.length; i++){
			labels[i] = new JLabel(labelNames[i]+": ");
			textFields[i] = new JTextField(8);
			if(labelNames[i].contains("Date")) textFields[i].setText(SqlUtils.getDateString(new Date()));
		}
		
		//Place the labels
		JPanel contentPane = new JPanel();
		setContentPane(contentPane);
		GridBagLayout gb = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		contentPane.setLayout(gb);
		contentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		
		for(i=0; i<labels.length; i++){
			c.gridwidth = GridBagConstraints.RELATIVE;
			c.insets = new Insets(10, 10, 5, 0);
			gb.setConstraints(labels[i], c);
			contentPane.add(labels[i]);
			
			// place the text field for the username
			if(type.equals(TableType.BORROWER) && i == labels.length - 1){
				comboBox = new JComboBox(new DefaultComboBoxModel(IoC.resolve(ClerkController.class).getService().getBorrowerTypes().keySet().toArray()));
				comboBox.addActionListener(new ActionListener(){

					@Override
					public void actionPerformed(ActionEvent e) {
						System.out.println("Type: " + comboBox.getSelectedItem());
						textFields[textFields.length - 1].setText((String)comboBox.getSelectedItem());
					}
					
				});
				c.gridwidth = GridBagConstraints.REMAINDER;
				c.insets = new Insets(10, -10, 5, 10);
				gb.setConstraints(comboBox, c);
				contentPane.add(comboBox);
				ClerkController cc = IoC.resolve(ClerkController.class);
				Set<String> keys = cc.getService().getBorrowerTypes().keySet();
				String[] borrowerTypes = keys.toArray(new String[0]);
				textFields[textFields.length - 1].setText(borrowerTypes[0]);
			}else{
				c.gridwidth = GridBagConstraints.REMAINDER;
				c.insets = new Insets(10, 0, 5, 10);
				gb.setConstraints(textFields[i], c);
				contentPane.add(textFields[i]);
			}
		}
		
		//Construct the DBOForm
		dboForm.setActionType(dialogType);
		dboForm.setTableType(type);
		
		//Construct the action button
		switch(dialogType){
		case INSERT:
			actionButton = new JButton("Insert");
			break;
		case UPDATE:
			actionButton = new JButton("Update");
			break;
		case DELETE:
			actionButton = new JButton("Delete");
			break;
		}
		actionButton.addActionListener(new ActionListener(){

			@Override
			public void actionPerformed(ActionEvent e) {
				//Set args to form object
				dboForm.initArgs(textFields.length);
				//System.out.println("Setting DBOForm Args: ");
				for(int i=0; i<textFields.length; i++) {
					dboForm.setArg(textFields[i].getText(), i);
					//System.out.print(textFields[i].getText() + ", ");
				}
				//System.out.println();
				dboController.performAction();
				parent.updateDBTables();
				StringBuilder builder = new StringBuilder();
				String[] args = dboForm.getArgs();
				for(int i=0; i<args.length-1; i++){
					builder.append(args[i]);
					builder.append(", ");
				}
				builder.append(args[args.length-1]);
				switch(dboForm.getActionType()){
				case INSERT:
					parent.appendText("Inserted: " + dboForm.getTableType().toString() + "\n" + builder.toString());
					break;
				case UPDATE:
					parent.appendText("Updated: " + dboForm.getTableType().toString() + "\n" + builder.toString());
					break;
				case DELETE:
					parent.appendText("Deleted: " + dboForm.getTableType().toString() + "\n" + builder.toString());
					break;
				}
				DBObjectDialog.this.setVisible(false);
				DBObjectDialog.this.dispose();
			}
			
		});
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(actionButton, c);
		contentPane.add(actionButton);
		
		//Cancle Button
		cancleButton = new JButton("NVM");
		cancleButton.addActionListener(new ActionListener(){
			
			@Override
			public void actionPerformed(ActionEvent arg0) {
				DBObjectDialog.this.setVisible(false);
				DBObjectDialog.this.dispose();
			}
			
		});
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.insets = new Insets(20, 20, 10, 10);
		gb.setConstraints(cancleButton, c);
		contentPane.add(cancleButton);
		
		//Finalize and show
		pack();
		setResizable(false);
		Point loc = frame.getLocationOnScreen();
		Dimension d = frame.getSize();
		setLocation(loc.x + (d.width - getWidth())/2, loc.y + (d.height - getHeight())/2);
	  	setDefaultCloseOperation(DISPOSE_ON_CLOSE);
	    setVisible(true);
	    textFields[0].requestFocus();
	}

}
